using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public delegate void CallBack();
public delegate void CallBack<T>(T t);
public delegate void CallBack<T, X>(T t, X x);

public static class EventHandler
{
    public static Dictionary<Events, Delegate> eventDic = new Dictionary<Events, Delegate>();

    private static void OnListenerAdding(Events eventKey, Delegate listenerDelegate)
    {
        if(!eventDic.ContainsKey(eventKey))
        {
            eventDic.Add(eventKey, null);
        }
    }

    public static void AddListener(Events eventType, CallBack handler)
    {
        OnListenerAdding(eventType, handler);
        eventDic[eventType] = (eventDic[eventType] as CallBack) + handler;
    }

    public static void AddListener<T>(Events eventType, CallBack<T> handler)
    {
        OnListenerAdding(eventType, handler);
        eventDic[eventType] = (eventDic[eventType] as CallBack<T>) + handler;
    }

    public static void AddListener<T, X>(Events eventType, CallBack<T, X> handler)
    {
        OnListenerAdding(eventType, handler);
        eventDic[eventType] = (eventDic[eventType] as CallBack<T, X>) + handler;
    }

    public static void RemoveListener(Events eventType)
    {
        eventDic[eventType] = null;
    }

    private static void OnDispatch(Events eventType)
    {
        if(!eventDic.ContainsKey(eventType))
            return;
    }

    public static void Dispatch(Events eventType)
    {
        OnDispatch(eventType);
        CallBack callback;
        if(eventDic.ContainsKey(eventType))
        {
            callback = eventDic[eventType] as CallBack;
            callback?.Invoke();
        }
    }

    public static void Dispatch<T>(Events eventType, T t)
    {
        OnDispatch(eventType);
        CallBack<T> callback;
        if(eventDic.ContainsKey(eventType))
        {
            callback = eventDic[eventType] as CallBack<T>;
            callback?.Invoke(t);
        }
    }

    public static void Dispatch<T, X>(Events eventType, T t, X x)
    {
        OnDispatch(eventType);
        CallBack<T, X> callback;
        if(eventDic.ContainsKey(eventType))
        {
            callback = eventDic[eventType] as CallBack<T, X>;
            callback?.Invoke(t, x);
        }
    }
}

public enum Events
{
    HitBrick,
    CallPauseMenu,
    NextLevel,
    ResetGame,
    EndGame,
    GetBuff,
    SpawnProp,
}